package com.polaris.live.im.db.entity

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.im.sfs.bean.chat.ext.SingleMessageExtBean
import com.polaris.live.im.sfs.bean.chat.ext.SingleMessagePayloadBean
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo

/**
 * 消息会话列表
 *
 * @author Created by 半仙 on 2023/8/22/022 16:32
 */
@Entity(
    tableName = "session",
    indices = [
        Index(value = ["user_id", "other_id"], unique = true)
    ]
)
data class SessionEntity(
    /**
     * 数据库主键
     */
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "table_id")
    val tableId: Int? = null,

    /**
     * 当前消息类型
     */
    @ColumnInfo(name = "command")
    var command: String,
    /**
     * 所属用户
     */
    @ColumnInfo(name = "user_id")
    val userId: Long,
    /**
     * 对方id
     *
     * 系统消息是0，陌生人消息是最后一个陌生人的id
     */
    @ColumnInfo(name = "other_id")
    val otherId: Long,
    /**
     * 发送者id
     */
    @ColumnInfo(name = "sender_id")
    val senderId: Long? = null,
    /**
     * 当前消息内容类型
     */
    @ColumnInfo(name = "type")
    val type: Long? = null,
    /**
     * 当前消息内容  存的json形式   根据type去解析即可
     */
    @ColumnInfo(name = "content")
    val content: String? = null,
    /**
     * timestamp时间戳
     */
    @ColumnInfo(name = "timestamp")
    val timestamp: Long? = null,

    /**
     * seqId 后端会传过来，有些地方后端需要
     */
    @ColumnInfo(name = "seq_id")
    val seqId: Long? = null,
    /**
     * 消息扩展  根据后续的业务可定
     */
    @ColumnInfo(name = "ext")
    val ext: String? = null,
    /**
     * 字段也是一个Json字符串，里面会存一些服务端填充和下发的东西
     */
    @ColumnInfo(name = "payload")
    val payload: String? = null,
    /**
     * 消息未读数
     */
    @ColumnInfo(name = "unread_count")
    var unreadCount: Long? = null,
    /**
     * 陌生人消息未读数，只有在陌生人列表才读取这个
     *
     * 具体设计为，总未读数只计算[unreadCount]，当陌生人的总未读数被清空时，这个未读数不会清空使得在陌生人里面的消息也能够展示未读数
     */
    @ColumnInfo(name = "stranger_unread_count")
    var strangerUnreadCount: Long? = null,

    /**
     * 是否为陌生人
     *
     * 这个值在自己发送过消息后将变为false
     */
    @ColumnInfo(name = "stranger_status")
    val strangerStatus: Boolean? = null,
    /**
     * 是否为系统推送消息
     *
     * 这个值在自己发送过消息后将变化null
     */
    @ColumnInfo(name = "greet_push_message")
    val greetPushMessage: Boolean? = null,

    /**
     * 这个数据主要用于缓存，在离线的情况下能够展示用户数据
     *
     * 获取应该使用[userBasic]
     */
    @ColumnInfo(name = "user_json")
    val userJson: String? = null
) {

    //---------- 本地状态

    /**
     * 是否状态变更
     *
     * 从陌生人变为熟人 或者 反之
     */
    @Ignore
    var isTranAcquaintance: Boolean = false

    fun isStranger(): Boolean {
        return strangerStatus == null || strangerStatus == true
    }

    fun isUpdatedState(): Boolean {
        return _updatedState
    }

    //---------- ui状态

    /**
     * 用户信息
     */
    @Ignore
    private var _user: UserBasicVo? = null

    /**
     * 上次更新session用户的时间
     */
    @Ignore
    private var _lastUpdateUserTime: Long? = null

    /**
     * 是否更新过状态，默认从数据库取出来状态的错误的，需要等待数据更新进来
     */
    @Ignore
    private var _updatedState: Boolean = false

    val userBasic: UserBasicVo?
        get() = _user ?: let {
            userJson?.let {
                JsonUtils.fromJson<UserBasicVo>(it).also { vo ->
                    _user = vo
                }
            }
        }

    fun updateUserBasic(userBasicVo: UserBasicVo?, isUpdateTime: Boolean = true) {
        val realUpdatedUser = userBasicVo !== _user
        _user = userBasicVo
        //真实更新了数据才更新
        if (userBasicVo != null && realUpdatedUser) {
            if (isUpdateTime) {
                _lastUpdateUserTime = CacheUtil.getServerTime()
            }
            _updatedState = true
        }
    }

    fun isUserEmpty(): Boolean {
        return userJson == null && _user == null
    }

    fun getLastUpdateUserTime(): Long? {
        return _lastUpdateUserTime
    }

    //---------- 其他数据

    @delegate:Ignore
    val extBean: SingleMessageExtBean? by lazy {
        if (ext.isNullOrEmpty()) {
            SingleMessageExtBean()
        } else {
            JsonUtils.fromJson<SingleMessageExtBean>(ext)
        }
    }

    @delegate:Ignore
    val payloadBean: SingleMessagePayloadBean? by lazy {
        if (payload.isNullOrEmpty()) {
            SingleMessagePayloadBean()
        } else {
            JsonUtils.fromJson<SingleMessagePayloadBean>(payload)
        }
    }
}